package com.ag.utils;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.MemoryCacheImageInputStream;

public class ImageUtil {

	// private static final Logger logger = LoggerFactory
	// .getLogger(ImageUtil.class);

	public static final String PNG = "png";
	public static final String JPG = "jpg";
	public static final String BMP = "bmp";
	public static final String GIF = "gif";

	public static byte[] readFromFile(String path) throws IOException {
		InputStream is = new FileInputStream(new File(path));
		return readFromFile(is);
	}
	
	public static byte[] readFromFile(InputStream is) throws IOException {
		byte[] buf = new byte[is.available()];
		is.read(buf);
		is.close();
		return buf;
	}

	public static ImageInfo getImageInfo(byte[] img) throws IOException {
		ByteArrayInputStream bais = new ByteArrayInputStream(img);
		MemoryCacheImageInputStream is = new MemoryCacheImageInputStream(bais);
		Iterator<ImageReader> it = ImageIO.getImageReaders(is);
		ImageReader r = null;
		if (it.hasNext()) {
			r = (ImageReader) it.next();
		}

		if (r == null) {
			return null;
		}
		ImageInfo i = new ImageInfo();
		i.setType(r.getFormatName().toLowerCase());
		int index = r.getMinIndex();

		synchronized (r) {
			r.setInput(is);
			i.setHeight(r.getHeight(index));
			i.setWidth(r.getWidth(index));
		}
		return i;
	}

	public static String fastParseFileType(byte[] byte1) {
		if ((byte1[0] == 71) && (byte1[1] == 73) && (byte1[2] == 70) && (byte1[3] == 56) && ((byte1[4] == 55) || (byte1[4] == 57)) && (byte1[5] == 97)) {
			return ImageUtil.GIF;
		}
		if (((byte1[6] == 0X45) && (byte1[7] == 0X78) && (byte1[8] == 0X69) && (byte1[9] == 0X66)) 
				|| ((byte1[6] == 74) && (byte1[7] == 70) && (byte1[8] == 73) && (byte1[9] == 70))) {
			return ImageUtil.JPG;
		}
		if ((byte1[0] == 66) && (byte1[1] == 77)) {
			return ImageUtil.BMP;
		}
		if ((byte1[1] == 80) && (byte1[2] == 78) && (byte1[3] == 71)) {
			return ImageUtil.PNG;
		}
		return null;
	}

	public static class ImageInfo {
		private String type;
		private int width;
		private int height;

		public String getType() {
			return this.type;
		}

		public void setType(String type) {
			this.type = type;
		}

		public int getWidth() {
			return this.width;
		}

		public void setWidth(int width) {
			this.width = width;
		}

		public int getHeight() {
			return this.height;
		}

		public void setHeight(int height) {
			this.height = height;
		}
	}

	public enum ImageScaleType {

		/**
		 * 把图片不按比例扩大/缩小到View的大小显示
		 */
		fitXY() {
			public Image clipImage(BufferedImage source, Integer clipedWidth, Integer clipedHeight, int[] imageSizes) {
				imageSizes[0] = clipedWidth;
				imageSizes[1] = clipedHeight;
				return source.getScaledInstance(clipedWidth, clipedHeight, Image.SCALE_SMOOTH);
			}
		},
		/**
		 * 将图片的内容完整居中显示，通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽
		 */
		centerInside() {
			public Image clipImage(BufferedImage source, Integer clipedWidth, Integer clipedHeight, int[] imageSizes) {
				// 1、等比例缩放
				int w = source.getWidth();
				int h = source.getHeight();
				double widthRate = clipedWidth.doubleValue() / w;
				double heightRate = clipedHeight.doubleValue() / h;
				if (widthRate <= heightRate) {
					imageSizes[0] = clipedWidth;
					imageSizes[1] = Double.valueOf(widthRate * h).intValue();

				} else {
					imageSizes[0] = Double.valueOf(heightRate * w).intValue();
					imageSizes[1] = clipedHeight;
				}
				// 2、按要求尺寸缩放
				return source.getScaledInstance(imageSizes[0], imageSizes[1], Image.SCALE_SMOOTH);
			}
		},
		/**
		 * 按图片的原来size居中显示，当图片长/宽超过View的长/宽，则截取图片的居中部分显示
		 */
		center() {
			public Image clipImage(BufferedImage source, Integer clipedWidth, Integer clipedHeight, int[] imageSizes) {
				imageSizes[0] = clipedWidth;
				imageSizes[1] = clipedHeight;
				Integer w = source.getWidth();
				Integer h = source.getHeight();
				double sourceRate = h.doubleValue() / w;
				double clipedRate = clipedHeight.doubleValue() / clipedWidth;

				int[] clipSourceimageSizes, subImagePoint;
				if (sourceRate <= clipedRate) {
					clipSourceimageSizes = new int[] { Double.valueOf(h / clipedRate).intValue(), h };
					subImagePoint = new int[] { (w - clipSourceimageSizes[0]) / 2, 0 };
				} else {
					clipSourceimageSizes = new int[] { w, Double.valueOf(clipedRate * w).intValue() };
					subImagePoint = new int[] { 0, (h - clipSourceimageSizes[1]) / 2 };
				}
				// source.getSubimage(subImagePoint[0], subImagePoint[1],
				// imageSizes[0], imageSizes[1]);

				// 2、按要求尺寸缩放
				return source.getSubimage(subImagePoint[0], subImagePoint[1], clipSourceimageSizes[0], clipSourceimageSizes[1]).getScaledInstance(clipedWidth, clipedHeight, Image.SCALE_SMOOTH);
			}
		};

		public abstract Image clipImage(BufferedImage source, Integer clipedWidth, Integer clipedHeight, int[] imageSizes);
	}

	public interface ImageSpecification {
		public Integer getWidth();

		public Integer getHeight();

		public Integer getCornerRadius();

		public Float getCompressQuality();

		public ImageScaleType getImageScaleType();

		public String getZoomedFileType(String originalFileType);
	}
	
	
	 /** 
     * 图片水印 
     * @param pressImg 水印图片 
     * @param targetImg 目标图片 
     * @param x 修正值 默认在中间 
     * @param y 修正值 默认在中间 
     * @param alpha 透明度 
     * @param waterPos 水印位置，有10种状态，0为指定位置；   
     *                 1为顶端居左，2为顶端居中，3为顶端居右；   
     *                 4为中部居左，5为中部居中，6为中部居右；   
     *                 7为底端居左，8为底端居中，9为底端居右；   
     */  
    public final static void pressImage(String pressImg, String targetImg, int x, int y, float alpha,int waterPos) {  
        try {  
            File img = new File(targetImg);  
            Image src = ImageIO.read(img);  
            int width = src.getWidth(null);  
            int height = src.getHeight(null);  
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            Graphics2D g = image.createGraphics();  
            g.drawImage(src, 0, 0, width, height, null);  
            //水印文件  
            Image src_biao = ImageIO.read(new File(pressImg));  
            int width_biao = src_biao.getWidth(null);  
            int height_biao = src_biao.getHeight(null);  
            int pos[] = setWaterPos(width,height,width_biao,height_biao,x,y,waterPos);  
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));  
            g.drawImage(src_biao, pos[0], pos[1], width_biao, height_biao, null);  
            //水印文件结束  
            g.dispose();  
            ImageIO.write((BufferedImage) image, "jpg", img);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
    
    /** 
     * 图片水印 
     * @param pressImg 水印图片 
     * @param targetImg 目标图片 
     * @param x 修正值 默认在中间 
     * @param y 修正值 默认在中间 
     * @param alpha 透明度 
     * @param waterPos 水印位置，有10种状态，0为指定位置；   
     *                 1为顶端居左，2为顶端居中，3为顶端居右；   
     *                 4为中部居左，5为中部居中，6为中部居右；   
     *                 7为底端居左，8为底端居中，9为底端居右；   
     */  
    public final static void pressImage(InputStream pressImg, String targetImg, int x, int y, float alpha,int waterPos) {  
        try {  
            File img = new File(targetImg);  
            Image src = ImageIO.read(img);  
            int width = src.getWidth(null);  
            int height = src.getHeight(null);  
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            Graphics2D g = image.createGraphics();  
            g.drawImage(src, 0, 0, width, height, null);  
            //水印文件  
            Image src_biao = ImageIO.read(pressImg);  
            int width_biao = src_biao.getWidth(null);  
            int height_biao = src_biao.getHeight(null);  
            int pos[] = setWaterPos(width,height,width_biao,height_biao,x,y,waterPos);  
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));  
            g.drawImage(src_biao, pos[0], pos[1], width_biao, height_biao, null);  
            //水印文件结束  
            g.dispose();  
            ImageIO.write((BufferedImage) image, "jpg", img);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    } 
    
    
    /** 
     * 文字水印 
     * @param pressText 水印文字 
     * @param targetImg 目标图片 
     * @param fontName 字体名称 
     * @param fontStyle 字体样式 
     * @param color 字体颜色 
     * @param fontSize 字体大小 
     * @param x 修正值 
     * @param y 正值 
     * @param alpha 透明度 
     */  
    public static void pressText(String pressText, String targetImg, String fontName, int fontStyle, Color color, int fontSize, int x, int y, float alpha,int waterPos) {  
        try {  
            File img = new File(targetImg);  
            Image src = ImageIO.read(img);  
            int width = src.getWidth(null);  
            int height = src.getHeight(null);  
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            Graphics2D g = image.createGraphics();  
            g.drawImage(src, 0, 0, width, height, null);  
            g.setColor(color);  
            g.setFont(new Font(fontName, fontStyle, fontSize));  
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));  
            int pos[] = setWaterPos(width,height,getLength(pressText) * fontSize,fontSize,x,y,waterPos);  
//          g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (height - fontSize) / 2 + y);  
            g.drawString(pressText, pos[0], pos[1]+fontSize);  
            g.dispose();  
            ImageIO.write((BufferedImage) image, "jpg", img);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
    /** 
     * 缩放 
     * @param filePath 图片路径 
     * @param height 高度 
     * @param width 宽度 
     * @param bb 比例不对时是否需要补白 
     */  
    public static void resize(String filePath, int height, int width, boolean bb) {  
        try {  
            double ratio = 0.0; //缩放比例   
            File f = new File(filePath);  
            BufferedImage bi = ImageIO.read(f);  
            Image itemp = bi.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);  
            //计算比例  
            if ((bi.getHeight() > height) || (bi.getWidth() > width)) {  
                if (bi.getHeight() > bi.getWidth()) {  
                    ratio = (new Integer(height)).doubleValue() / bi.getHeight();  
                } else {  
                    ratio = (new Integer(width)).doubleValue() / bi.getWidth();  
                }  
                AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);  
                itemp = op.filter(bi, null);  
            }  
            if (bb) {  
                BufferedImage image =   
                 new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
                Graphics2D g = image.createGraphics();  
                g.setColor(Color.white);  
                g.fillRect(0, 0, width, height);  
                if (width == itemp.getWidth(null))  
                    g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);  
                else  
        g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);  
                g.dispose();  
                itemp = image;  
            }  
            ImageIO.write((BufferedImage) itemp, "jpg", f);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
  
    public static int getLength(String text) {  
        int length = 0;  
        for (int i = 0; i < text.length(); i++) {  
            if (new String(text.charAt(i) + "").getBytes().length > 1) {  
                length += 2;  
            } else {  
                length += 1;  
            }  
        }  
        return length / 2;  
    }  
  
  
    private static int[]  setWaterPos(int ground_w,int ground_h,int w_width,int w_height,int width,int height,int waterPos){  
        int pos[] = new int[2];   
        switch (waterPos) {  
        case 0:    //0为指定位置  
            pos[0]=width;  
            pos[1]=height;  
            break;  
        case 1:   //1为顶端居左   
            pos[0]=0;  
            pos[1]=0;  
        break;  
        case 2:  //2为顶端居中  
            pos[0]=(ground_w - w_width) / 2;  
            pos[1]=0;  
        break;  
        case 3:  //3为顶端居右     
            pos[0]=ground_w - w_width;  
            pos[1]=0;  
        break;  
        case 4:  //4为中部居左  
            pos[0]=0;  
            pos[1]=(ground_h - w_height) / 2;  
        break;   //5为中部居中  
        case 5:  
            pos[0]=(ground_w - w_width) / 2;  
            pos[1]=(ground_h - w_height) / 2;  
        break;  //6为中部居右  
        case 6:  
            pos[0]=ground_w - w_width;  
            pos[1]=(ground_h - w_height) / 2;  
        break;  
        case 7:  //7为底端居左   
            pos[0]=0;  
            pos[1]=ground_h - w_height;  
        break;  
        case 8:  //8为底端居中  
            pos[0]=(ground_w - w_width) / 2;  
            pos[1]=ground_h - w_height;  
        break;  
        case 9: //9为底端居右  
            pos[0]=ground_w - w_width;  
            pos[1]=ground_h - w_height;  
        break;  
        default:  //指定位置  
            pos[0]=width;  
            pos[1]=height;  
        break;  
        }  
        return pos;  
    } 
}